package com.znow.admin.config;

import com.znow.admin.filter.JwtAuthenticationTokenFilter;
import com.znow.admin.system.security.authentication.SmsCodeAuthConfig;
import com.znow.admin.system.security.handel.CustomAuthorizeErrorHandler;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * WebSecurityConfigurer配置
 *
 * @author Nemo
 * @date 2022/09/23
 */
@AllArgsConstructor
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * md5密码编码器
     */
    private final Md5PasswordEncoder md5PasswordEncoder;

    /**
     * 用户详细信息服务
     */
    private final UserDetailsService userDetailsService;

    /**
     * jwt身份验证令牌过滤器
     */
    private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    /**
     * 自定义授权错误处理程序
     */
    private final CustomAuthorizeErrorHandler customAuthorizeErrorHandler;

    private final SmsCodeAuthConfig smsCodeAuthConfig;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(md5PasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                headers().frameOptions().disable().and()
                // 禁用缓存
                .headers().cacheControl().and().and()
                // 防止csrf攻击
                .csrf().disable()
                // 不创建session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .and()
                .authorizeRequests().antMatchers(
                        "/sys/login",
                        "/sys/logout").permitAll()
                .and()
                // 所有请求都需要认证
                .authorizeRequests().anyRequest().authenticated().and()
                .formLogin()
                .disable();
        // 加入短信验证码过滤器配置
        // http.apply(smsCodeAuthConfig);
        // 加入jwt拦截器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // http.exceptionHandling().accessDeniedHandler(customAuthorizeErrorHandler);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        /**
         * 不过滤前端资源
         **/
        web.ignoring().antMatchers(HttpMethod.GET, "/**/*.js",
                "/**/*.css",
                "/**/*.uijs",
                "/**/*.uicss",
                "/**/*.woff2*",
                "/**/*.woff*",
                "/**/*.ttf*",
                "/**/*.png",
                "/**/*.gif",
                "/**/*.jpg",
                "/**/*.mp3",
                "/**/*.css.map",
                "/**/*.js.map",
                "/uiengine.uijs",
                "/uiengine.uicss",
                "/**/*.ico",
                "/v2/api-docs",
                "/swagger/**",
                "/v2/api-docs",
                "/swagger-resources/**",
                "/swagger/**",
                "/swagger-ui.html",
                "/swagger-ui.html",
                "/swagger-resources/**",
                "/webjars/springfox-swagger-ui/**",
                "/v2/api-docs/**",
                "/",
                "/swagger-resources/configuration/security",
                "/csrf",
                "/actuator/**",
                "/druid/*");
    }

    /**
     * 身份验证管理器
     *
     * @return {@link AuthenticationManager}
     * @throws Exception 异常
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

}
